home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / public / pbmplus / pgm / pgmtolispm.c < prev    next >
C/C++ Source or Header  |  1994-08-01  |  4KB  |  144 lines

  1. /* pgmtolispm.c - read a pgm and write a file acceptable to the 
  2. ** tv:read-bit-array-file function of TI Explorer and Symbolics Lisp Machines.
  3. **
  4. ** Written by Jamie Zawinski based on code (C) 1988 by Jef Poskanzer.
  5. **
  6. ** Permission to use, copy, modify, and distribute this software and its
  7. ** documentation for any purpose and without fee is hereby granted, provided
  8. ** that the above copyright notice appear in all copies and that both that
  9. ** copyright notice and this permission notice appear in supporting
  10. ** documentation.  This software is provided "as is" without express or
  11. ** implied warranty.
  12. **
  13. **   When one writes a multi-plane bitmap with tv:write-bit-array-file, it is
  14. **   usually a color image; but a color map is not written in the file, so we
  15. **   treat this as a graymap instead.  To convert a color image to Lispm 
  16. **   format, you must convert it to a pgm, and hand-edit a color map...  Ick.
  17. */
  18.  
  19. #include <stdio.h>
  20. #include "pgm.h"
  21.  
  22. #define LISPM_MAGIC  "This is a BitMap file"
  23.  
  24. static void putinit ARGS(( int cols, int rows, int depth ));
  25. static int depth_to_word_size ARGS(( int depth ));
  26. static void putval ARGS(( gray b ));
  27. static void putrest ARGS(( void ));
  28. static void putitem ARGS(( void ));
  29.  
  30. void
  31. main( argc, argv )
  32.     int argc;
  33.     char* argv[];
  34.     {
  35.     FILE* ifp;
  36.     gray *grayrow;
  37.     register gray* gP;
  38.     int rows, cols, depth, format, padright, row, col;
  39.     gray maxval;
  40.  
  41.     pgm_init( &argc, argv );
  42.  
  43.     if ( argc > 2 )
  44.     pm_usage( "[pgmfile]" );
  45.     if ( argc == 2 )
  46.     ifp = pm_openr( argv[1] );
  47.     else
  48.     ifp = stdin;
  49.  
  50.     pgm_readpgminit( ifp, &cols, &rows, &maxval, &format );
  51.     grayrow = pgm_allocrow( cols );
  52.     depth = pm_maxvaltobits( maxval );
  53.  
  54.     /* Compute padding to round cols up to the nearest multiple of 32. */
  55.     padright = ( ( cols + 31 ) / 32 ) * 32 - cols;
  56.  
  57.     putinit( cols, rows, depth );
  58.     for ( row = 0; row < rows; ++row )
  59.     {
  60.     pgm_readpgmrow( ifp, grayrow, cols, maxval, format );
  61.         for ( col = 0, gP = grayrow; col < cols; ++col, ++gP )
  62.         putval( *gP );
  63.     for ( col = 0; col < padright; ++col )
  64.         putval( 0 );
  65.         }
  66.  
  67.     pm_close( ifp );
  68.  
  69.     putrest( );
  70.  
  71.     exit( 0 );
  72.     }
  73.  
  74. static unsigned int item;
  75. static unsigned int bitsperitem, maxbitsperitem, bitshift;
  76.  
  77. static void
  78. putinit( cols, rows, depth )
  79.     int cols, rows, depth;
  80.     {
  81.     int i;
  82.     int cols32 = ( ( cols + 31 ) / 32 ) * 32;    /* Lispms are able to write bit files that are not mod32 wide, but we   */
  83.                         /* don't.  This should be ok, since bit arrays which are not mod32 wide */
  84.     printf(LISPM_MAGIC);            /* are pretty useless on a lispm (can't hand them to bitblt).        */
  85.     pm_writelittleshort( stdout, cols );
  86.     pm_writelittleshort( stdout, rows );
  87.     pm_writelittleshort( stdout, cols32 );
  88.     putchar(depth & 0xFF);
  89.  
  90.     for ( i = 0; i < 9; ++i )
  91.     putchar( 0 );    /* pad bytes */
  92.  
  93.     item = 0;
  94.     bitsperitem = 0;
  95.     maxbitsperitem = depth_to_word_size( depth );
  96.     bitshift = 0;
  97.     }
  98.  
  99. static int
  100. depth_to_word_size (depth)    /* Lispm architecture specific - if a bitmap is written    */
  101.   int depth;            /* out with a depth of 5, it really has a depth of 8, and  */
  102. {                /* is stored that way in the file.               */
  103.     if (depth==0 || depth==1)    return ( 1);
  104.     else if (depth ==  2)    return ( 2);
  105.     else if (depth <=  4)    return ( 4);
  106.     else if (depth <=  8)    return ( 8);
  107.     else if (depth <= 16)    return (16);
  108.     else if (depth <= 32)    return (32);
  109.     else
  110.       pm_error( "depth was %d, which is not in the range 1-32", depth );
  111. }
  112.  
  113. #if __STDC__
  114. static void
  115. putval( gray b )
  116. #else /*__STDC__*/
  117. static void
  118. putval( b )
  119. gray b;
  120. #endif /*__STDC__*/
  121.     {
  122.     if ( bitsperitem == 32 )
  123.     putitem( );
  124.     item = item | ( b << bitshift );
  125.     bitsperitem = bitsperitem + maxbitsperitem;
  126.     bitshift = bitshift + maxbitsperitem;
  127.     }
  128.  
  129. static void
  130. putrest( )
  131.     {
  132.     if ( bitsperitem > 0 )
  133.     putitem( );
  134.     }
  135.  
  136. static void
  137. putitem( )
  138.     {
  139.     pm_writelittlelong( stdout, ~item );
  140.     item = 0;
  141.     bitsperitem = 0;
  142.     bitshift = 0;
  143.     }
  144.